package com.jinzhi.jzsynthesize.controller;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.type.EnumErrorCode;
import com.jinzhi.common.utils.EhCacheUtil;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.ValidUtils;
import com.jinzhi.jzsynthesize.ExcelVo.FeedbackVo;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.pojo.ErroeDownVo;
import com.jinzhi.jzweb.pojo.ErrorCodeVo;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.jzweb.utils.ValuesUtil;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * 考试调度
 */
@Controller
@AllArgsConstructor
@RequestMapping("/synthesize/dispatch")
public class ExamDispatchController extends BaseController {

	@Autowired
	private TestFeedbackService testFeedbackService;
	@Autowired
	private ExaminationBatchService examinationBatchService;
	@Autowired
	private OrganizationNewsService organizationNewsService;
	@Autowired
	private UserService userService;
	@Autowired
	private OrganizationRolesService organizationRolesService;
	@Autowired
	private StuSignUpService stuSignUpService;


	@GetMapping()
	@RequiresPermissions("jzweb:dispatch:dispatch")
	String TestFeedback(){
		return "synthesizeWeb/dispatch/dispatch";
	}

	@Log("考试调度列表")
	@ResponseBody
	@GetMapping("/list")
	@RequiresPermissions("jzweb:dispatch:dispatch")
	public Result<Page<TestFeedbackDO>> list(HttpServletRequest req,TestFeedbackDO testFeedbackDTO){
		Wrapper<TestFeedbackDO> wrapper = new EntityWrapper<TestFeedbackDO>().orderBy("id", false);

		//查询用户角色
		String roleName = getRoleNames();
		if (!roleName.contains("超级用户角色")) {
			Object orgId = req.getSession().getAttribute("orgId");
			if (orgId != null){
				wrapper.eq("org_id" , orgId);
			}else {
				wrapper.eq("org_id" , this.getUser().getOrgId());
			}

		}

		if (testFeedbackDTO.getEbatchId() != null){
			wrapper.eq("ebatch_id" , testFeedbackDTO.getEbatchId());
		}
		Page<TestFeedbackDO> page = testFeedbackService.selectPage(getPage(TestFeedbackDO.class), wrapper);
		List list = new ArrayList();
		for (int i = 0; i < page.getRecords().size(); i++) {
			TestFeedbackDO obj = (TestFeedbackDO) page.getRecords().get(i);
			if (obj.getEbatchId() != null){
				ExaminationBatchDO examinationBatchDO = examinationBatchService.selectById(obj.getEbatchId());
				if (examinationBatchDO != null) {
					obj.setEbatchName(examinationBatchDO.getName());
					if (examinationBatchDO.getType() == 0){
						obj.setType("理论考试");
					}else if (examinationBatchDO.getType() == 1){
						obj.setType("技能考试");
					}else if (examinationBatchDO.getType() == 2){
						obj.setType("社会实践");
					}
				}
			}
			if (obj.getOrgId() != null){
				OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(obj.getOrgId());
				if (organizationNewsDO != null) {
					obj.setOrgName(organizationNewsDO.getName());
				}
			}
			if (obj.getUserId() != null){
				UserDO userDO = userService.selectById(obj.getUserId());
				if (userDO != null) {
					if (userDO.getName()!= null){
						obj.setUserName(userDO.getName());
					}else {
						obj.setUserName(userDO.getUsername());
					}
				}
			}
			if (obj.getMissStuId() != null){
				UserDO userDO = userService.selectById(obj.getMissStuId());
				if (userDO != null) {
					obj.setMissStuName(userDO.getName());
				}
			}
			if (obj.getCheatStuId() != null){
				UserDO userDO = userService.selectById(obj.getCheatStuId());
				if (userDO != null) {
					obj.setCheatStuName(userDO.getName());
				}
			}
			list.add(obj);
		}
		page.setRecords(list);
		return Result.ok(page);
	}


	@Log("查询考试批次列表-无分页")
	@ResponseBody
	@GetMapping("/eBatch")
	Result<?> findEBatchLists(){
		Wrapper<ExaminationBatchDO> wrapper = new EntityWrapper<>();
		wrapper.eq("state" , 5);
//		wrapper.eq("type" , 1);

		List<ExaminationBatchDO> eBatchList = examinationBatchService.selectList(wrapper);

		return Result.ok(eBatchList);
	}

	@GetMapping("/add")
	@RequiresPermissions("jzweb:dispatch:add")
	String add(){
		return "synthesizeWeb/dispatch/add";
	}

	@GetMapping("/edit/{id}")
	@RequiresPermissions("jzweb:dispatch:edit")
	String edit(@PathVariable("id") Long id, Model model){
		TestFeedbackDO testFeedback = testFeedbackService.selectById(id);
		model.addAttribute("testFeedback", testFeedback);
		return "synthesizeWeb/dispatch/edit";
	}

	@Log("添加考试调度")
	@ResponseBody
	@PostMapping("/save")
	@RequiresPermissions("jzweb:dispatch:add")
	public Result<String> save( TestFeedbackDO testFeedback){
		testFeedbackService.insert(testFeedback);
		return Result.ok();
	}

	@Log("修改考试调度")
	@ResponseBody
	@RequestMapping("/update")
	@RequiresPermissions("jzweb:dispatch:edit")
	public Result<String>  update( TestFeedbackDO testFeedback){
		boolean update = testFeedbackService.updateById(testFeedback);
		return update ? Result.ok() : Result.fail();
	}

	@Log("删除考试调度")
	@PostMapping( "/remove")
	@ResponseBody
	@RequiresPermissions("jzweb:testFeedback:remove")
	public Result<String>  remove( Long id){
		testFeedbackService.deleteById(id);
		return Result.ok();
	}

	@Log("批量删除考试调度")
	@PostMapping( "/batchRemove")
	@ResponseBody
	@RequiresPermissions("jzweb:dispatch:batchRemove")
	public Result<String>  remove(@RequestParam("ids[]") Long[] ids){
		testFeedbackService.deleteBatchIds(Arrays.asList(ids));
		return Result.ok();
	}

	/**
	 * 下载导入模板
	 *
	 * @param response
	 */
	@RequestMapping("/download")
	@RequiresPermissions("jzweb:dispatch:import")
	@ResponseBody
	public void downloadImportTemplate(HttpServletResponse response) {
		List<FeedbackVo> list = new LinkedList<>();
		//导出操作
		EasyPoiUtil.exportExcel(list, "综合管理平台-考试调度", "考试调度导入模板", FeedbackVo.class, "综合管理平台-考试调度", response);
	}


	/**
	 * 考试调度信息导入
	 *
	 * @param feedbackFiles excel文件
	 */
	@Log("考试调度信息导入")
	@PostMapping("/import")
	@ResponseBody
	@Transactional
	@RequiresPermissions("jzweb:dispatch:import")
	public Result<?> importExcel(HttpServletRequest req,@RequestParam("feedbackFiles") MultipartFile feedbackFiles, String eBatchId) {
		//---------------------------------检测导入信息及条件-----------------------------------------
		//第一步--判断文件格式
		if (!"application/vnd.ms-excel".equals(feedbackFiles.getContentType())) {
			return Result.fail("文件格式错误，请选择.xls文件");
		}

		//第二步--解析文件获得数据
		List<FeedbackVo> list = EasyPoiUtil.importExcel(feedbackFiles, 1, 1, FeedbackVo.class);
		if (list.size() == 0) {
			return Result.fail("Excel数据为空，请完善");
		}

		//第三步--判断导入人员身份，获取导入人员信息
		OrganizationNewsDO organizationNewsDOss = new OrganizationNewsDO();
		//todo 超级管理员是否需要判断导入信息
		if (this.getUser().getOrgId() != null) {
			OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(this.getUser().getOrgId());
			if (organizationNewsDO == null) {
				return Result.fail("您的所属机构信息错误，无法导入信息！");
			} else {
				Object orgId = req.getSession().getAttribute("orgId");
				if (orgId != null){
					OrganizationRolesDO organizationRolesDOs = organizationRolesService.findOneByKv("org_id", orgId, "role_type", 5);
					if (organizationRolesDOs == null) {
						return Result.fail("您的所属机构不具备考核站点角色，无法导入信息！");
					}
				}else {
					OrganizationRolesDO organizationRolesDOs = organizationRolesService.findOneByKv("org_id", this.getUser().getOrgId(), "role_type", 5);
					if (organizationRolesDOs == null) {
						return Result.fail("您的所属机构不具备考核站点角色，无法导入信息！");
					}
				}
				organizationNewsDOss = organizationNewsDO;
			}
		}
		int startRow = 3;
		int cout = 1;//错误信息计数
		List<TestFeedbackDO> upDOList = new ArrayList<>();
		List<ErrorCodeVo> list1 = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			StringBuilder sb = new StringBuilder();
			//第一步验证是否存在空值
			if (StringUtils.isBlank(list.get(i).getName())) {
				sb.append("第" + (i + startRow) + "行姓名未填写，请完善！" + ";");
			} else {
				if (StringUtils.isBlank(list.get(i).getMobile())) {
					sb.append("第" + (i + startRow) + "行手机号码未填写，请完善！" + ";");
				} else {
					if (StringUtils.isBlank(list.get(i).getIsCheat())) {
						sb.append("第" + (i + startRow) + "行是否作弊未填写，请完善！" + ";");
					} else {
						if (!list.get(i).getIsCheat().equals("是") && !list.get(i).getIsCheat().equals("否")){
							sb.append("第" + (i + startRow) + "行是否作弊填写错误，请填写“是”或“否”" + ";");
						}
						if (StringUtils.isBlank(list.get(i).getIsMiss())) {
							sb.append("第" + (i + startRow) + "行是否缺考未填写，请完善" + ";");
						} else {
							if (!list.get(i).getIsMiss().equals("是") && !list.get(i).getIsMiss().equals("否")){
								sb.append("第" + (i + startRow) + "行是否缺考填写错误，请填写“是”或“否”" + ";");
							}
							if (StringUtils.isBlank(list.get(i).getIsAbnormal())){
								sb.append("第" + (i + startRow) + "行是否异常未填写，请完善" + ";");
							}else {
								if (!list.get(i).getIsAbnormal().equals("是") && !list.get(i).getIsAbnormal().equals("否")){
									sb.append("第" + (i + startRow) + "行是否异常填写错误，请填写“是”或“否”" + ";");
								}
								if (StringUtils.isBlank(list.get(i).getAbnormalContent())){
									sb.append("第" + (i + startRow) + "行异常内容未填写，请完善" + ";");
								}else {
									if (StringUtils.isBlank(list.get(i).getOtherContent())){
										sb.append("第" + (i + startRow) + "行其他反馈内容未填写，请完善" + ";");
									}
								}
							}
							//第二步验证电话号码
							if (!ValidUtils.isMobile(list.get(i).getMobile())) {
								sb.append("第" + (i + startRow) + "行手机号码格式错误，请完善！" + ";");
							} else {
								if(sb.length() == 0){
									//第四步排重验证（自身比较）
									for (int j = 0; j < list.size(); j++) {
										if (i != j) {
											if (list.get(i).getMobile().equals(list.get(j).getMobile())) {
												sb.append("第" + (i + startRow) + "行跟第" + (j + startRow) + "行手机号重复，重复值：" + list.get(i).getMobile() + ";");
											}
										}
									}
									//根据手机号码获取用户信息并判断
									UserDO userDO = userService.findOneByKv("mobile", list.get(i).getMobile());
									if (userDO == null){
										sb.append("第" + (i + startRow) + "行该考生用户信息不存在，请修改后重新上传！" + ";");
									}else {
										ExaminationBatchDO exam = examinationBatchService.selectById(eBatchId);

										StuSignUpDO stu = stuSignUpService.findOneByKv("user_id" , userDO.getId() , "cbatch_id" ,exam.getCbatchId());
										if (stu == null){
											sb.append("第" + (i + startRow) + "行该考生报名信息不存在，请修改后重新上传！" + ";");
										}else {
											if (!stu.getOrgId().equals(this.getUser().getOrgId())){
												sb.append("第" + (i + startRow) + "行，您不能导入非本考点的考生反馈信息，请修改后重新上传！" + ";");
											}else {
												TestFeedbackDO tests = testFeedbackService.findOneByKv("ebatch_id" , eBatchId, "cheat_stu_id" , userDO.getId(), "miss_stu_id", userDO.getId());
												if (tests != null){
													sb.append("第" + (i + startRow) + "行该考试批次下已存在考生姓名为“" + userDO.getName() + "”的考生请修改完善后重新上传！;");
												}else {
													TestFeedbackDO test = new TestFeedbackDO();
													test.setUserId(this.getUserId());
													test.setCheatStuId(userDO.getId());
													test.setMissStuId(userDO.getId());
													test.setEbatchId(Long.parseLong(eBatchId));
													test.setOrgId(this.getUser().getOrgId());
													if (list.get(i).getIsCheat().equals("是")) {
														test.setIsCheat(0);
													}else {
														test.setIsCheat(1);
													}
													if (list.get(i).getIsMiss().equals("是")) {
														test.setIsMiss(0);
													}else {
														test.setIsMiss(1);
													}
													if (list.get(i).getIsAbnormal().equals("是")) {
														test.setIsAbnormal(0);
													}else {
														test.setIsAbnormal(1);
													}
													test.setOtherContent(list.get(i).getOtherContent());
													test.setState(0);
													//转换一下图片路径，将反斜杠替换掉
													if (list.get(i).getFeedbackFiles()!= null){
														String url = list.get(i).getFeedbackFiles().replace(ValuesUtil.localUrl, ValuesUtil.returnUrl);
														String fileUrl = url.replace("\\", "/");
														test.setFeedbackFiles(fileUrl);
													}
													test.setAbnormalContent(list.get(i).getAbnormalContent());
													upDOList.add(test);

												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			if (sb.length() > 0) {
				ErrorCodeVo errorCodeVo = new ErrorCodeVo();
				errorCodeVo.setSeq(cout);
				cout += 1;
				errorCodeVo.setErrorCode(sb.toString());
				list1.add(errorCodeVo);
			}
		}
		if (list1.size() == 0) {
			boolean c = testFeedbackService.insertBatch(upDOList, upDOList.size());
			if (c) {
				return Result.ok("成功导入" + list.size() + "条数据");
			} else {
				return Result.fail("考试调度信息添加错误，请稍后重试或联系管理员");
			}
		} else {

			JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list1));
			//将list1存到缓存中
			EhCacheUtil.put("test" + this.getUserId(), jsonArray);
			return Result.build(EnumErrorCode.FileImportError.getCode(), EnumErrorCode.FileImportError.getMsg());
		}
	}

	/**
	 * 导出错误信息
	 */
	@Log("导出错误信息")
	@GetMapping("/importError")
	@ResponseBody
	@Transactional
	@RequiresPermissions("jzweb:dispatch:import")
	public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 告诉浏览器用什么软件可以打开此文件
		response.setHeader("content-Type", "application/vnd.ms-excel");
		// 下载文件的默认名称
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("考试调度信息导入错误信息", "UTF-8") + ".xls");
		//编码
		response.setCharacterEncoding("UTF-8");
		String jsonArray = EhCacheUtil.get("test" + this.getUserId()).toString();
		JSONArray arrayList = JSONArray.parseArray(jsonArray);
		//转换为目标对象list
		List<ErroeDownVo> groupList = JSONObject.parseArray(arrayList.toJSONString(), ErroeDownVo.class);
		Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ErroeDownVo.class, groupList);
		workbook.write(response.getOutputStream());
	}

}
